/**
 * Window action
 */
package cn.antia.cwin.page;

import java.util.*;

import javax.servlet.http.*;

import cn.antia.cep.common.*;
import cn.antia.cep.common.pool.*;
import cn.antia.cwin.grid.AntiaNormalTable;
import cn.antia.cwin.window.*;
import cn.antia.cep.page.*;
import cn.antia.cwin.page.StrutsAction;
import cn.antia.cep.page.action.ActionException;
import cn.antia.cep.page.po.WindowQueryCond;
import cn.antia.cwin.SysConf;
import cn.antia.cwin.ValiableInjector;
import cn.antia.cwin.Cele;
import cn.antia.cwin.ConfigPoolHelper;
import cn.antia.util.StringUtil;

/**
 * @author sunkeei
 * @date Dec 2, 2007
 * @time 8:25:20 PM
 * @version 0.1
 */
public class WindowAction extends StrutsAction {
	private SingleWindow window;
    private WindowService windowService;
    public WindowService getWindowService() {
		return windowService;
	}
	public void setWindowService(WindowService windowService) {
		this.windowService = windowService;
	}
    private ValiableInjector valiableInjector;
    public ValiableInjector getValiableInjector() {
		return valiableInjector;
	}
	public void setValiableInjector(ValiableInjector valiableInjector) {
		this.valiableInjector = valiableInjector;
	}
	private AntiaPoolHelper antiaPoolHelper;
	public AntiaPoolHelper getAntiaPoolHelper() {
		return antiaPoolHelper;
	}
	public void setAntiaPoolHelper(AntiaPoolHelper antiaPoolHelper) {
		this.antiaPoolHelper = antiaPoolHelper;
	}
	/**
     * Method execute
     * @return ActionForward ActionForward
     */
    public String action() throws ActionException {
        window = null;
        //action
        String action = request.getParameter("action") == null ? "" : request.getParameter("action");
        String windowSessionId = request.getParameter(WindowConst.JWAS_SINGLE_WINDOW_ID);
        if(windowSessionId != null){
        	window = (SingleWindow)session.getAttribute(windowSessionId);
        	request.setAttribute(WindowConst.JWAS_SINGLE_WINDOW_ID,windowSessionId);
        }
        if(window == null){
        	init(request);
        }else{
        	String windowId = window.getId();
	        /**根据ACTION分支处理*/
	        if (action.equals("query")){
	            queryAction(windowId, request);
	        } else if (action.equals("update")) {
	        	modifyAction(windowId, request);
	        	return "ok";
	        } else if (action.equals("delete")) {
	            deleteAction(windowId, request);
	            return "ok";
	        }else if(action.equals("goPage")){
	        	goPage(windowId,request);
	        }else if(action.equals("edit")){
	        	toEdit();
	        	return "edit";
	        }else if(action.equals("add")){
	        	toAdd();
	        	return "edit";
	        }
        }
        return "single";
    }
    
    private void toEdit() {
		String id = request.getParameter("id");
		Map<Cele,Object> eles = windowService.get(window.getId(), Integer.parseInt(id));
		//设置值
		String fieldName;
		List<Cele> fields;
		for(Map.Entry<Cele,Object> entry:eles.entrySet()){
			fieldName = entry.getKey().getField().getFieldName();
			fields = window.getFields();
			for(Cele ec2:fields){
				if(fieldName.equals(ec2.getField().getFieldName())){
                    eles.put(ec2,entry.getValue().toString());
				}
			}
		}
	}
    private void toAdd() {
    	//String id = request.getParameter("id");
	}

    /**
     * 查询处理
     * @param winId 表名
     * @param request 请求
     *
     * @throws cn.antia.cep.page.action.ActionException a
     */
    protected void queryAction(String winId, HttpServletRequest request) throws ActionException {
    	//扩展字段
        Map<Cele,Object> additiveFields = new HashMap<Cele,Object>();
        //组建查询对象与值
        Map<Cele,Object> conditions = this.getFieldValues(request, QUERY,additiveFields);
        //查询并返回结果
        AntiaNormalTable table = windowService.query(winId, conditions, additiveFields);
        WindowQueryCond cond = new WindowQueryCond(conditions,additiveFields);
        setSessionQueryCache(winId, cond);
        fillPage(winId, table);
    }
    
    /**
     * 查询处理
     * @param winId 表名
     * @param request 请求
     *
     * @throws cn.antia.cep.page.action.ActionException a
     */
    protected void goPage(String winId, HttpServletRequest request) throws ActionException {
        WindowQueryCond cond = getQueryCache(winId);
        String toPage = request.getParameter("toPage");
        int page = Integer.parseInt(toPage);
        //查询并返回结果
        AntiaNormalTable table = windowService.query(winId, cond.getConditions(), cond.getAdditive(),page);
        fillPage(winId, table);
    }

    /**
     * 更新
     * 处理 (add or undate)
     * @param winId 表名
     * @param request 请求
     * @throws cn.antia.cep.page.action.ActionException a
     */
    protected void modifyAction(String winId,HttpServletRequest request) throws ActionException {
    	Map<Cele,Object> other = new HashMap<Cele,Object>();
        Map<Cele,Object> elements = this.getFieldValues(request, UPDATE,other);
        if (elements == null || elements.size() < 1) {
        	return;
        }
        boolean hasId = false;
        for (Map.Entry<Cele, Object> entry : elements.entrySet()) {
            Cele ec = entry.getKey();
            if (ec.getField().getFieldName().equalsIgnoreCase(SysConf.KEY_FIELD)) {
                hasId = true;
                break;
            }
        }
        //如果有ID，则更新，否则，新增记录
        if (hasId) {
        	windowService.update(winId, elements, other);
        } else {
        	windowService.insert(winId, elements, other);
        }
        //将查询结果转为页面显示对象，存入request
        fillPage(winId, null);
    }

    /**
     * 删除
     * 处理
     * @param winId 表名
     * @param request 请求对象
     * @throws cn.antia.cep.page.action.ActionException a
     */
    protected void deleteAction(String winId,HttpServletRequest request) throws ActionException {
        String id = request.getParameter(SysConf.KEY_FIELD);
        //附加属性
        Map<Cele,Object> other = new HashMap<Cele,Object>();
        //查询条件
        Map<Cele,Object> conditions = this.getFieldValues(request,DELETE,other);
        //如果ID不为空，则直接删除该ID对应的记录
        if (id == null || id.equals("")) {
            if(conditions != null && conditions.size() > 0){
            	windowService.delete(winId,conditions,other);
            }else{
            	request.setAttribute("message", "没有指定要删除的数据。");
            }
        } else {
        	windowService.delete(winId, Integer.parseInt(id), other);
        }
        fillPage(winId, null);
    }
    
    /**
     * 取出参数构造List对象返回
     * @param request request
     * @param type 操作类型
     * @param additiveEles additiveEles
     * @return  List
     * @throws cn.antia.cep.page.action.ActionException e
     */
    protected Map<Cele,Object> getFieldValues(HttpServletRequest request, int type,Map<Cele,Object> additiveEles) throws ActionException{
    	List<Cele> additive = new ArrayList<Cele>();
        
        Map<Cele,Object> elements = new HashMap<Cele,Object>();
        Cele ec = new Cele();
        String paraName;
        String paraValue;
        String errmsg;
        Map map = request.getParameterMap();
        for (Object o : map.keySet()) {
            paraName = (String) o;
            paraValue = request.getParameter(paraName).trim();
            if (paraValue != null && paraValue.indexOf("-PRE-") == 0) {
                paraValue = paraValue.substring(5);
            }
            if (paraName.equalsIgnoreCase("action")) {
                continue;
            }
            //如果没有找到，那就是附加属性
            if (window.hasField(paraName)) {        //附加属性
                //查看是否在已有的附加属性里面
                ec = new Cele();
                //如果有，设置其值，如果没有，加上他
                if (ec == null) {
                    ec = new Cele();
                    ec.getField().setFieldName(paraName);
                    additive.add(ec);
                }else{
                    elements.put(ec,paraValue);
                }
                continue;
            }
            /**
             * 增加操作ID不参与
             * 查询操作加密字段不参与
             * */
            switch (type) {
                case QUERY:
                    if (ec.isEncrypt() || paraName.equals(SysConf.KEY_FIELD) || ec.getField().getDefault() != null || paraValue == null || paraValue.trim().length() < 1) {
                        continue;
                    }
                    break;
                case DELETE:
                    if (ec.isEncrypt()) {
                        continue;
                    }
            }

            if (paraValue != null && paraValue.equals(SysConf.NEW_VALUE)) {
                continue;
            }
            //加密字符
            if (paraValue != null && !paraValue.equals("")) {
                if (ec.isEncrypt()) {
                    paraValue = SampleEncryption.getEncryptString(paraValue);
                }
            }
            //如果为空并且不是字符串，则不更新数据库
            if (paraValue == null || paraValue.equals("")) {
                if (!(ec.getField().getJavaType().equals("string"))) {
                    continue;
                }
            }
            //如果是隐藏字段并且值为空，则不更新
            if (ec.getHtmlWidget().getHtmlType().equals("hidden") && paraValue.trim().equals("")) {
                continue;
            }
            //设置值(是否有系统默认值，有则加上)
            elements.put(ec, paraValue);
        }
        if (type != ADD && type != UPDATE) {
            convertHtmlChar(elements);
        }
        //验证
        List<String> errs = validateElement(elements);
        if (errs != null && errs.size() > 0) {
            request.setAttribute("err_msg", StringUtil.arrayToString(errs,"<BR/>"));
            return null;
        }
        //增加新增时的新建值与修改时的修改值
        if(type == ADD){
        	List<Cele> createFields = Window.getCreateValueFields(ConfigPoolHelper.getComsats(window.getTable()));
    		elements = Window.addIfNotExist(elements,createFields);
        }else if(type == UPDATE){
        	List<Cele> modifyFields = Window.getModifyValueFields(ConfigPoolHelper.getComsats(window.getTable()));
    		elements = Window.addIfNotExist(elements,modifyFields);
        }
        //设置系统变量
        valiableInjector.setSysValiables(type, elements, request);
        return elements;
    }

    /**
     * 转换为页面对象
     * 设置Request
     * @param winId 表名
     * @param at table data
     * @throws cn.antia.cep.page.action.ActionException cc
     */
    public void fillPage(String winId, AntiaNormalTable at) throws ActionException {
        if (at == null || at.getRows() == null) {
            request.setAttribute("message", "没有查询到任何结果");
		}
		request.setAttribute(PageRule.getTableSessionName(winId),at);
	}
	
	private List<String> validateElement(Map<Cele,Object> eles) {
        List<String> err = new ArrayList<String>();
        for (Map.Entry<Cele, Object> entry : eles.entrySet()) {
            Cele ec = entry.getKey();
            String str = entry.getValue().toString();
            //空判断
            if (ec.getField().getAllowNull() == null || !ec.getField().getAllowNull()) {
                if (!ec.getField().isKey() && (str == null || str.equals(""))) {
                    err.add(ec.getField().getFieldName() + " 不能为空!");
                }
            }
            //类型判断

            //其它判断以后再加
        }
        return err;
    }
	private void convertHtmlChar(Map<Cele,Object> eles) {
        for (Map.Entry<Cele, Object> entry : eles.entrySet()) {
            String str = entry.getValue().toString();
            str = str.replaceAll("&amp;", "&");
            eles.put(entry.getKey(),str);
        }
    }
	
	/**
	 * 将Window信息装入session
	 * @param request HttpServletRequest
	 */
	protected void init(HttpServletRequest request){
		String id = request.getParameter("id");		//window id
		boolean isMulti = false;					//是否允许同一页面存在两个相同ID的window
		if(id == null || id.trim().length() < 1){
			ActionException ae = new ActionException("012","Not get a window ID");
			SysExceptionTool.addExceptionInfo(ae);
			throw ae;
		}
		window = antiaPoolHelper.getSingleWindow(id);
		if(window == null){
			ActionException ae = new ActionException("012","Not found a window by ID=" + id);
			SysExceptionTool.addExceptionInfo(ae);
			throw ae;
		}
		Map map = request.getParameterMap();
        Iterator pamas = map.keySet().iterator();
        String parm,pvalue;
        Cele ec = new Cele();
        while(pamas.hasNext()){
        	parm = (String)pamas.next();
        	pvalue = request.getParameter(parm);
        	//是否可以在同一页面出现多个相同ID的WINDOW
        	if(parm.equals("multi")){
        		isMulti = true;
        		continue;
        	}
        	//如果指定action
        	if(parm.equals("was")){
        		window.setAction(pvalue);
        		continue;
        	}
        	if(parm.equals("id")){
        		continue;
        	}
        	//查看是否有这个字段
        	//如果有，则设置其默认值
        	if(window.hasField(parm)){
        		ec.getHtmlWidget().setAttr("readonly","true");
        		Cele.setValitionString(ec);
        	}
           /* else{

               // 附加字段另做处理---080722注释
                //如果没有，则查看是否在附加字段中已有定义
        		ecadd = Window.existField(window.getAdditive(), parm);
        		//如果在附加字段中有定义，那么覆盖之前定义
        		if(ecadd != null){
        			ecadd.setValue(pvalue);
        			ecadd.getHtmlWidget().setAttr("readonly","true");
        		}

                else{
        			//如果在附加字段中没有定义，则加入到附加字段中
        			ecadd = new Cele();
        			ecadd.getHtmlWidget().setHtmlType("hidden");
        			ecadd.getField().setFieldName(parm);
        			ecadd.setValue(pvalue);
        			ecadd.getHtmlWidget().setAttr("readonly","true");

                    List list = window.getAdditive();
        			if(list == null) list = new ArrayList();
        			list.add(ecadd);
        			window.setAdditive(list);

                }
        	}*/
        }
        if(!isMulti){
        	//通知页面，当前的windowId
        	request.setAttribute(WindowConst.JWAS_SINGLE_WINDOW_ID,id);
        	session.setAttribute(id,window);
        }else{
        	throw new AntiaException("000","方法未实现,windowAction:multi");
        }
        
	}
	
	/**
     * 将Grid的查询状态保存在Session中，以便翻页时调用这个查询状态
     * @param winId	ID
     * @param cond	查询条件
     */
    private void setSessionQueryCache(String winId,WindowQueryCond cond){
    	HashMap map = (HashMap)session.getAttribute(SessionConst.WINDOW_QUERY_CACHE);
    	if(map == null){
    		map = new HashMap();
    		session.setAttribute(SessionConst.WINDOW_QUERY_CACHE, map);
    	}
    	map.put(winId, cond);
    }
    /**
     * 取得保存在Session中的查询条件
     * @param winId winId
     * @return WindowQueryCond
     */
    private WindowQueryCond getQueryCache(String winId){
    	HashMap map = (HashMap)session.getAttribute(SessionConst.WINDOW_QUERY_CACHE);
    	return (WindowQueryCond)map.get(winId);
    }
}